﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraBars;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;
using System.Threading;
using System.Xml;
using System.Diagnostics;

namespace MusicDownloaderFix
{
    public partial class frmMain : DevExpress.XtraBars.Ribbon.RibbonForm, IFrmMain
    {
        List<StreamMusic> lsMusic = new List<StreamMusic>();

        static protected internal string strAddress;
        static protected internal string strSaveTo;
        static protected internal string strIDM;
        static protected internal bool bIDM;
        static protected internal int maxDownload;
        string folder;
        static protected internal bool bRename;  // chon doi ten hoac ghi de file bi trung. true: doi ten

        Stopwatch watch = new Stopwatch();
        int countDown;
        Thread thread;
        string dir;
        StreamMusic music = new StreamMusic();

        public frmMain()
        {
            InitializeComponent();
        }

        public void btnAdd_ItemClick(object sender, ItemClickEventArgs e)
        {
            var frm = new frmAddURL();
            //if (frm.ShowDialog() == System.Windows.Forms.DialogResult.OK
            //    && Directory.Exists(strSaveTo.Trim()))
            if(frm.ShowDialog()  == System.Windows.Forms.DialogResult.OK)
            {
                    GetLinks();
            }

            btnDownload.Enabled = true;
        }

        //get links from multiaddress input

        public void GetLinks()
        {
            try
            {
                try
                {
                    string str = strAddress.Trim(); //dia chi web nhac
                    if (str != string.Empty)
                    {
                        //if (Directory.Exists(strSaveTo.Trim()))
                        if(true)
                        {
                            //this.btnGetLink.Enabled = false;
                            //this.toolStripStatusLabel1.Text = "Đang xử lý...";
                            //this.btnGetLink.Enabled = false;
                            //this.btnCheckAll.Enabled = false;
                            //this.btnClean.Enabled = false;
                            //this.btnUnCheckAll.Enabled = false;
                            //this.btnCheckItemUnComplete.Enabled = false;
                            //this.comboBox1.Enabled = false;
                            //this.btnResetLink.Enabled = false;
                            char[] chrArray = new char[1];
                            chrArray[0] = ';';
                            string[] strArrays = str.Split(chrArray, StringSplitOptions.RemoveEmptyEntries);
                            int num = 0;
                            while (num < strArrays.Length)
                            {
                                string hTMLFromPage = GetHTMLFromPage(strArrays[num].Trim());
                                if (hTMLFromPage.Length >= 0)
                                {
                                    if (!strArrays[num].Contains("nhaccuatui.com"))
                                    {
                                        if (strArrays[num].Contains("mp3.zing.vn") && !this.LoadStreamMp3Zing(strArrays[num], hTMLFromPage))
                                        {
                                            return;
                                        }
                                    }
                                    else
                                    {
                                        if (!this.LoadStreamNhacCuaTui(strArrays[num], hTMLFromPage))
                                        {
                                            return;
                                        }
                                    }
                                    num++;
                                }
                                else
                                {
                                    MessageBox.Show("Không thể tải trang web. Vui lòng kiểm tra lại liên kết!", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Hand);
                                    return;
                                }
                            }
                            //if (this.listView1.Items.Count != 0)
                            //{
                            //    this.txtMusickeys.Text = "";
                            //    this.txtMusickeys.Focus();
                            //    this.btnCheckAll.Enabled = true;
                            //    this.btnClean.Enabled = true;
                            //    this.btnUnCheckAll.Enabled = true;
                            //    this.btnCheckItemUnComplete.Enabled = true;
                            //    this.btnResetLink.Enabled = true;
                            //    this.toolStripStatusLabel1.Text = "Lấy file nhạc thành công";
                            //}
                            //else
                            //{
                            //    MessageBox.Show("Không tìm thấy file nhạc. Vui lòng kiểm tra lại!", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                            //}
                        }
                        else
                        {
                            MessageBox.Show("Vui lòng chọn đường dẫn lưu file cần tải", "Chú ý", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                            //this.txtSaveto.Focus();
                            return;
                        }
                    }
                    else
                    {
                        MessageBox.Show("Vui lòng nhập liên kết web nhạc", "Chú ý", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                        //this.txtMusickeys.Focus();
                        return;
                    }
                }
                catch (WebException webException)
                {
                    MessageBox.Show("Lỗi kết nối server. Vui lòng kết nối lại!", "Lỗi", MessageBoxButtons.OK, MessageBoxIcon.Hand);
                    //this.toolStripStatusLabel1.Text = "Lỗi kết nối server";
                }
                catch (Exception exception1)
                {
                    Exception exception = exception1;
                    MessageBox.Show(exception.Message, "Lỗi", MessageBoxButtons.OK, MessageBoxIcon.Hand);
                    //this.toolStripStatusLabel1.Text = "Lỗi";
                }
            }
            finally
            {
                //this.btnGetLink.Enabled = true;
                //this.btnCheckAll.Enabled = true;
                //this.btnClean.Enabled = true;
                //this.btnUnCheckAll.Enabled = true;
                //this.btnCheckItemUnComplete.Enabled = true;
                //this.comboBox1.Enabled = true;
            }
        }

        public static string GetHTMLFromPage(string linkPage)
        {
            HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(linkPage);
            httpWebRequest.Method = "GET";
            HttpWebResponse response = (HttpWebResponse)httpWebRequest.GetResponse();

            string strHTML = string.Empty;
            StreamReader reader = null;

            try
            {
                reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                strHTML = reader.ReadToEnd();
            }
            catch (Exception)
            {
                MessageBox.Show("Lỗi đọc html", "Lỗi");
            }
            finally
            {
                if (reader!=null)
                {
                    reader.Close();
                }

                response.Close();
            }
            
            return strHTML;
        }

        //get information of link

        public bool LoadStreamMp3Zing(string linkPage, string html)
        {
            string empty = string.Empty;
            string str = string.Empty;
            MatchCollection matchCollections = Regex.Matches(html, "(http://mp3.zing.vn[\\w\\d:#@%/;$()~_?\\+-=\\\\\\.&]*xml[^>]*)");
            str = "http://mp3.zing.vn";
            if (matchCollections.Count <= 0)
            {
                MessageBox.Show("Không tìm thấy liên kết chứa file nhạc. Bạn hãy kiểm tra liên kết trang nhạc!", "Lỗi", MessageBoxButtons.OK, MessageBoxIcon.Hand);
                return false;
            }
            else
            {
                empty = matchCollections[1].Groups[0].Value.Replace("\"", "");
                matchCollections = Regex.Matches(html, "(?<=(<title>))(?<=)(.*?)(?=(</title>)|(Album)|(Playlist))");
                if (matchCollections.Count > 0)
                {
                    this.folder = matchCollections[0].Groups[0].Value.Replace("|", "").Trim();
                }

                string path = empty.Substring(0, empty.IndexOf('&'));

                XmlReaderSettings setting = new XmlReaderSettings();
                setting.IgnoreComments = true;
                setting.IgnoreWhitespace = true;

                XmlReader reader = XmlReader.Create(path, setting);

                if (reader.ReadToDescendant("item"))
                {
                    do
                    {
                        reader.ReadStartElement("item");

                        var music = new StreamMusic
                        {
                            FileName = reader.ReadElementContentAsString()
                                + " - " + reader.ReadElementContentAsString(),
                            Link = reader.ReadElementContentAsString(),
                        };

                        lsMusic.Add(music);
                    } while (reader.ReadToFollowing("item"));
                }

                reader.Close();

                gridControl1.DataSource = lsMusic;

                //XmlDocument xmlDocument = new XmlDocument();
                //Thread.Sleep(0x7d0);
                //xmlDocument.LoadXml(GetXMLStream(empty, str));
                ////this.toolStripStatusLabel1.Text = string.Concat("Lấy liên kết thành công: ", linkPage);
                //XmlNodeList elementsByTagName = xmlDocument.GetElementsByTagName("location");
                //XmlNodeList xmlNodeLists = xmlDocument.GetElementsByTagName("title");
                //XmlNodeList elementsByTagName1 = xmlDocument.GetElementsByTagName("annotation");
                //for (int i = 0; i < elementsByTagName.Count; i++)
                //{
                //    if (elementsByTagName[i].InnerText != string.Empty)
                //    {
                //        ListViewItem listViewItem = new ListViewItem();
                //        string empty1 = string.Empty;
                //        if (this.CheckSameItemName(string.Concat(xmlNodeLists[i].InnerText.Trim(), " - ", 
                //            elementsByTagName1[i].InnerText.Trim(), 
                //            elementsByTagName[i].InnerText.Substring(elementsByTagName[i].InnerText.LastIndexOf((char)46)).Trim()), out empty1))
                //        {
                //            listViewItem.Text = empty1;
                //            listViewItem.SubItems.Add(elementsByTagName[i].InnerText).Name = "Links";
                //            listViewItem.SubItems.Add("").Name = "Status";
                //            if (elementsByTagName.Count <= 1)
                //            {
                //                char[] chrArray = new char[1];
                //                chrArray[0] = '\\';
                //                listViewItem.SubItems.Add(strSaveTo.Trim(chrArray)).Name = "Saveto";
                //            }
                //            else
                //            {
                //                char[] chrArray1 = new char[1];
                //                chrArray1[0] = '\\';
                //                listViewItem.SubItems.Add(string.Concat(strSaveTo.Trim(chrArray1), "\\", this.Folder)).Name = "Saveto";
                //            }
                //            listViewItem.SubItems.Add("").Name = "ID";
                //            listViewItem.Checked = true;
                //            this.listView1.Items.Add(listViewItem);
                //        }
                //    }
                //}
                return true;
            }
        }

        private static string GetXMLStream(string url, string domain)
        {
            string str;
            try
            {
                string empty = string.Empty;
                string[] strArrays = new string[0];
                if (!url.Contains("nhaccuatui"))
                {
                    if (url.Contains("mp3.zing.vn"))
                    {
                        int num = url.LastIndexOf((char)47);
                        empty = string.Concat("key=", url.Substring(num + 1));
                    }
                }
                else
                {
                    char[] chrArray = new char[1];
                    chrArray[0] = '?';
                    strArrays = url.Split(chrArray);
                    empty = strArrays[1];
                }
                HttpWebRequest length = (HttpWebRequest)WebRequest.Create(url);
                //length.Method = "POST";
                //length.ContentType = "application/x-www-form-urlencoded";
                //length.ContentLength = empty.Length;
                //length.Referer = domain;
                //WebHeaderCollection webHeaderCollection = new WebHeaderCollection();
                //webHeaderCollection.Set("host", domain);
                //byte[] bytes = Encoding.UTF8.GetBytes(empty);
                //Stream requestStream = length.GetRequestStream();
                //using (requestStream)
                //{
                //    requestStream.Write(bytes, 0, (int)bytes.Length);
                //    requestStream.Close();
                //}
                string end = string.Empty;
                HttpWebResponse response = (HttpWebResponse)length.GetResponse();
                using (StreamReader streamReader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
                {
                    end = streamReader.ReadToEnd();
                    streamReader.Close();
                }
                response.Close();
                str = end;
            }
            catch (Exception exception1)
            {
                Exception exception = exception1;
                throw new Exception(exception.Message);
            }
            return str;
        }

        public bool CheckSameItemName(string fileName, out string fileNameNew)
        {
            fileNameNew = fileName;
            int num = 1;
            //for (int i = 0; i < this.listView1.Items.Count; i++)
            //{
            //    if (this.listView1.Items[i].Text.ToLower().Equals(fileNameNew.ToLower()))
            //    {
            //        if (bSelected != true)
            //        {
            //            if (bSelected == false)
            //            {
            //                return false;
            //            }
            //        }
            //        else
            //        {
            //            string str = fileName.Substring(0, fileName.LastIndexOf((char)46));
            //            string str1 = fileName.Substring(fileName.LastIndexOf((char)46));
            //            int num1 = i;
            //            while (true)
            //            {
            //                fileNameNew = string.Concat(str, "_", num.ToString(), str1);
            //                if (this.listView1.Items[num1].Text.ToLower() != fileNameNew.ToLower())
            //                {
            //                    break;
            //                }
            //                num++;
            //            }
            //        }
            //    }
            //}
            return true;
        }

        private bool LoadStreamNhacCuaTui(string linkPage, string html)
        {
            string empty = string.Empty;
            string str = string.Empty;
            MatchCollection matchCollections = Regex.Matches(html, "(http://[\\w\\d:#@%/;$()~_?\\+-=\\\\\\.&]*ashx([?\\d\\w=\\d]*))");
            str = "http://www.nhaccuatui.com";
            if (matchCollections.Count <= 0)
            {
                MessageBox.Show("Không tìm thấy liên kết chứa file nhạc. Bạn hãy kiểm tra liên kết trang nhạc!", "Lỗi", MessageBoxButtons.OK, MessageBoxIcon.Hand);
                return false;
            }
            else
            {
                empty = matchCollections[1].Groups[0].Value.Replace("\"", "");
                matchCollections = Regex.Matches(html, "<h1><a[^>]*>(.*?)</a></h1>");
                if (matchCollections.Count > 0)
                {
                    this.folder = matchCollections[0].Groups[1].Value;
                }

                XmlReaderSettings setting = new XmlReaderSettings();
                setting.IgnoreComments = true;
                setting.IgnoreWhitespace = true;

                XmlReader reader = XmlReader.Create(empty, setting);

                if (reader.ReadToDescendant("track"))
                {
                    do
                    {
                        reader.ReadStartElement("track");

                        var music = new StreamMusic
                        {
                            FileName = reader.ReadElementContentAsString()
                                + " - " + reader.ReadElementContentAsString(),
                            Link = reader.ReadElementContentAsString(),
                        };

                        lsMusic.Add(music);
                    } while (reader.ReadToFollowing("track"));
                }

                reader.Close();

                gridControl1.DataSource = lsMusic;

                //XmlDocument xmlDocument = new XmlDocument();
                //xmlDocument.LoadXml(GetXMLStream(empty, str));
                //this.toolStripStatusLabel1.Text = string.Concat("Lấy liên kết thành công: ", linkPage);
                //XmlNodeList elementsByTagName = xmlDocument.GetElementsByTagName("location");

                //for (int i = 0; i < elementsByTagName.Count; i++)
                //{
                //    if (elementsByTagName[i].InnerText != string.Empty)
                //    {
                //        ListViewItem listViewItem = new ListViewItem();
                //        string empty1 = string.Empty;
                //        if (this.CheckSameItemName(elementsByTagName[i].InnerText.Substring(elementsByTagName[i].InnerText.LastIndexOf((char)47) + 1), out empty1))
                //        {
                //            listViewItem.Text = empty1;
                //            listViewItem.SubItems.Add(elementsByTagName[i].InnerText).Name = "Links";
                //            listViewItem.SubItems.Add("").Name = "Status";
                //            if (elementsByTagName.Count <= 1)
                //            {
                //                char[] chrArray = new char[1];
                //                chrArray[0] = '\\';
                //                listViewItem.SubItems.Add(strSaveTo.Trim(chrArray)).Name = "Saveto";
                //            }
                //            else
                //            {
                //                char[] chrArray1 = new char[1];
                //                chrArray1[0] = '\\';
                //                listViewItem.SubItems.Add(string.Concat(strSaveTo.Trim(chrArray1), "\\", this.Folder)).Name = "Saveto";
                //            }
                //            listViewItem.Checked = true;
                //            listViewItem.SubItems.Add("").Name = "ID";
                //            this.listView1.Items.Add(listViewItem);
                //        }
                //    }
                //}
                return true;
            }
        }

        public void btnOption_ItemClick(object sender, ItemClickEventArgs e)
        {
            var frm = new frmOption();
            if (frm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                return;
            }
        }

        public void frmMain_Load(object sender, EventArgs e)
        {
            DisableOnStart(false);
        }
  
        public void DisableOnStart(bool p)
        {
            //btnDownload.Enabled = p;
            btnDelete.Enabled = p;
            btnResume.Enabled = p;
            btnStop.Enabled = p;
            btnReset.Enabled = p;
        }

        private void btnDownload_ItemClick(object sender, ItemClickEventArgs e)
        {
            //ShowContentLength(path);

            if (bIDM)
            {
                DownloadWithIDM();
            }
            else
            {
                DownloadWithC();
            }
                
            //%UserProfile%
        }

        private void DownloadWithIDM()
        {
            Process process = new Process();

            process.StartInfo.FileName = strIDM;
            //process.StartInfo.CreateNoWindow = true;

            if (process.Start())
            {
                process.WaitForInputIdle();

                int i = 0;

                foreach (var item in lsMusic)
                {
                    AddToIDM(item.Link);

                    gridView1.SetRowCellValue(i++, "Status", "Download with IDM");
                }
            }

            process.StartInfo.Arguments = "/s";
            process.Start();
        }

        private void AddToIDM(string path)
        {
            Process.Start(strIDM, "/n /a /q /d \"" + path + "\" ");
            Thread.Sleep(200);
        }

        private void ShowContentLength(string path)
        {
            WebRequest req = WebRequest.Create(path);
            req.Method = "HEAD";
            WebResponse resp = req.GetResponse();

            int size;

            if (int.TryParse(resp.Headers.Get("Content-Length"), out size))
            {
                if (size > 1048576)
                    labelControl2.Text = (size / 1048576.00).ToString(".00 MB");
                else if (size > 1024)
                    labelControl2.Text = (size / 1024.00).ToString(".00 KB");
                else
                    labelControl2.Text = size + " B";
                //Do something useful with ContentLength here 
            }

            resp.Close();
        }

        private void DownloadWithC()
        {
            countDown = maxDownload;

            dir = strSaveTo + "\\" + folder;

            Directory.CreateDirectory(dir);
               

            foreach (var item in lsMusic)
            {
                music = item;
                //thread = new Thread(new ThreadStart(Download));
                //thread.Start();
                //thread.Join();
                //thread.Suspend();

                Download();
            }
        }

        private void Download()
        {
            WebClient client = new WebClient();

            client.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
            client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
            client.DownloadFileAsync(new Uri(music.Link), dir + "\\" + music.FileName + ".mp3");

            watch.Restart();
        }

        private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            progressBar.EditValue = e.ProgressPercentage;
            labelControl1.Text = e.ProgressPercentage.ToString();

            labelControl3.Text = (e.BytesReceived * 1000.00 / 1024 / watch.ElapsedMilliseconds).ToString(".00 KB/sec");

        }

        private void Completed(object sender, AsyncCompletedEventArgs e)
        {
            MessageBox.Show("Download completed!");

            watch.Stop();
        }
        
    }
}